﻿Public Class CustomDocumentPaginator
    Inherits DocumentPaginator

    Private mPageSize As Size
    Private mMargin As Size
    Private mPaginator As DocumentPaginator
    Private mTypeface As Typeface

    Public Sub New(ByVal paginator As DocumentPaginator,
                   ByVal pageSize As Size,
                   ByVal margin As Size,
                   ByVal headerHeight As Double,
                   ByVal footerHeight As Double)
        mPageSize = pageSize
        mMargin = margin
        mPaginator = paginator
        HeaderOffset = headerHeight
        FooterOffset = footerHeight

        mPaginator.PageSize = ComputePageSize()
    End Sub

#Region "Additional Properties"

    Private mHeaderVisual As Visual
    Public Property HeaderVisual As Visual
        Get
            Return mHeaderVisual
        End Get
        Set(ByVal Value As Visual)
            mHeaderVisual = Value
        End Set
    End Property

    Private mTemplatePage As DocumentPage
    Public Property TemplatePage As DocumentPage
        Get
            Return mTemplatePage
        End Get
        Set(ByVal Value As DocumentPage)
            mTemplatePage = Value
        End Set
    End Property

    Public Property HeaderOffset As Double
    Public Property FooterOffset As Double

#End Region

#Region "Paginator Implementation"

    Private Function Move(ByVal rect As Rect) As Rect
        If rect.IsEmpty Then
            Return rect
        Else
            Return New Rect(rect.Left + mMargin.Width, rect.Top + mMargin.Height, rect.Width, rect.Height)
        End If
    End Function

    Public Overrides Function GetPage(ByVal pageNumber As Integer) As DocumentPage
        Dim page As DocumentPage = mPaginator.GetPage(pageNumber)

        ' Create a wrapper visual for transformation and add extras
        Dim newpage As New ContainerVisual()

        If Not TemplatePage Is Nothing Then
            Dim background As New DrawingVisual()
            'todo - make background color, and presence optional
            Using ctx As DrawingContext = background.RenderOpen()
                ctx.DrawRectangle(New SolidColorBrush(Color.FromRgb(248, 248, 255)),
                                  Nothing,
                                  TemplatePage.ContentBox)
            End Using
            newpage.Children.Add(background)

            Dim header As New DrawingVisual
            Using ctx As DrawingContext = header.RenderOpen()
                ctx.DrawRectangle(New VisualBrush(TemplatePage.Visual), Nothing, TemplatePage.ContentBox)
            End Using
            newpage.Children.Add(header)
            header.Transform = New MatrixTransform(0.95, 0, 0, 0.95,
                                                        0.025 * TemplatePage.ContentBox.Width,
                                                        0.025 * TemplatePage.ContentBox.Height)
        End If


        ' Scale down page and center
        Dim innerPage As New ContainerVisual()
        innerPage.Children.Add(page.Visual)
        innerPage.Transform = New MatrixTransform(0.95, 0, 0, 0.95,
                                                    0.025 * page.ContentBox.Width,
                                                    (0.025 * page.ContentBox.Height) + 0)

        newpage.Children.Add(innerPage)


        newpage.Transform = New TranslateTransform(mMargin.Width, mMargin.Height)

        Return New DocumentPage(newpage, mPageSize, Move(page.BleedBox), Move(page.ContentBox))
    End Function

    Public Overrides ReadOnly Property IsPageCountValid() As Boolean
        Get
            Return mPaginator.IsPageCountValid
        End Get
    End Property

    Public Overrides ReadOnly Property PageCount() As Integer
        Get
            Return mPaginator.PageCount
        End Get
    End Property

    Public Overrides Property PageSize() As Size
        Get
            Return mPageSize
            'Return mPaginator.PageSize
        End Get

        Set(ByVal value As Size)
            mPageSize = value
            mPaginator.PageSize = ComputePageSize()
        End Set
    End Property

    Private Function ComputePageSize() As Size
        Return New Size(mPageSize.Width - mMargin.Width * 2,
                            mPageSize.Height - (mMargin.Height * 2) - HeaderOffset - FooterOffset)
    End Function

    Public Overrides ReadOnly Property Source() As IDocumentPaginatorSource
        Get
            Return mPaginator.Source
        End Get
    End Property

#End Region

End Class

